<?php
/**
 * KayPaste
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * @category   KayPaste
 * @package    Controller
 * @subpackage Plugins
 * @copyright  Copyright (c) 2007-2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
 * @author     Robin Skoglund
 */

/**
 * Imports
 * 
 * @see Zend_Auth
 * @see Zend_Controller_Action_HelperBroker
 * @see Zend_Controller_Plugin_Abstract
 * @see Zym_Acl
 */
require_once 'Zend/Auth.php';
require_once 'Zend/Controller/Action/HelperBroker.php';
require_once 'Zend/Controller/Plugin/Abstract.php';
require_once 'Zym/Acl.php';
require_once 'Zym/Controller/Action/Helper/FlashRedirector.php';

/**
 * Plugin for handling authentication and authorization
 *
 * @category   KayPaste
 * @package    Controller
 * @subpackage Plugins
 * @copyright  Copyright (c) 2007-2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
 * @author     Robin Skoglund
 */
class Kaypaste_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
    /**
     * Auth instance
     *
     * @var Zend_Auth
     */
    protected $_auth;
    
    /**
     * ACL instance
     *
     * @var Zym_Acl
     */
    protected $_acl;
    
    /**
     * Where to go to if user is not authenticated
     *
     * @var array
     */
    protected $_noAuth = array(
        'module'     => 'user',
        'controller' => 'login',
        'action'     => 'index'
    );

    /**
     * Where to go to if user is not authorized
     *
     * @var array
     */
    protected $_noAcl = array(
        'module'     => 'default',
        'controller' => 'error',
        'action'     => 'privileges'
    );
    
    /**
     * Constructs plugin
     * 
     */
    public function __construct()
    {
        $this->_acl = new Zym_Acl();
        $this->_acl->addRole(new Zend_Acl_Role('guest'));
        $this->_acl->addRole(new Zend_Acl_Role('member'), 'guest');
        $this->_acl->addRole(new Zend_Acl_Role('admin'), 'member');
        $this->_acl->allow('admin');
    }
    
    /**
     * Redirects to the specified location for when user is not authenticated
     *
     * @return void
     */
    protected function _redirectNoAuth()
    {
        $redir = 'Redirector';
        $redir = Zend_Controller_Action_HelperBroker::getStaticHelper($redir);
        $redir->gotoSimpleAndExit($this->_noAuth['action'],
                                  $this->_noAuth['controller'],
                                  $this->_noAuth['module']);
    }
    
    /**
     * Redirects to the specified location for when user is not authorized
     *
     * @return void
     */
    protected function _redirectNoAcl()
    {
        $redir = 'Redirector';
        $redir = Zend_Controller_Action_HelperBroker::getStaticHelper($redir);
        $redir->gotoSimpleAndExit($this->_noAcl['action'],
                                  $this->_noAcl['controller'],
                                  $this->_noAcl['module']);
    }
    
    /**
     * Returns auth instance
     *
     * @return Zend_Auth
     */
    public function getAuth()
    {
        if ($this->_auth === null) {
            $this->_auth = Zend_Auth::getInstance();
        }
        
        return $this->_auth;
    }

    /**
     * Authenticate user before dispatch
     *
     * @param  Zend_Controller_Request_Abstract $request
     * @return void
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $auth = $this->getAuth();
        
        if ($auth->hasIdentity()) {
            return;
        }
        
        $module = $request->getModuleName();
        $controller = $request->getControllerName();
        $action = $request->getActionName();
        
        if (($module == 'user' && $controller == 'login') ||
            ($module == 'default' && $controller == 'error')) {
            // do nothing for now
        } else {
            $fr = new Zym_Controller_Action_Helper_FlashRedirector();
            $fr->setRedirect($_SERVER['REQUEST_URI']);
            $this->_redirectNoAuth();
        }
    }
}
